package com.kapo.egroup.controller;

import cn.hutool.core.util.ObjectUtil;
import com.kapo.egroup.common.ResponseEnum;
import com.kapo.egroup.common.Result;
import com.kapo.egroup.entity.base.lesson.UserLessonRecord;
import com.kapo.egroup.entity.base.project.Project;
import com.kapo.egroup.entity.base.project.UserApplyRecord;
import com.kapo.egroup.entity.base.project.UserInviteRecord;
import com.kapo.egroup.entity.base.project.UserProjectRecord;
import com.kapo.egroup.entity.base.user.User;
import com.kapo.egroup.security.domain.LoginUser;
import com.kapo.egroup.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
 * @Title ProjectController
 * @Description TODO
 * @Author 86159
 * @Date 2023-03-31 20:37
 **/
@RestController
@RestControllerAdvice
@RequestMapping("/api")
public class ProjectController {
    @Autowired
    private ProjectService projectService;

    @Autowired
    private InviteService inviteService;

    @Autowired
    private ApplyService applyService;

    @Autowired
    private UserService userService;

    @Autowired
    private LessonService lessonService;

    /**
     * @descriptions 获取我的课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.eintern.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @GetMapping("/project")
    public Result getMyProject() throws Exception{
        List<Project> projectList = projectService.getMyProjects(getCurrentUserId());
        System.out.println(projectList);
        return Result.ok(projectList);
    }
    /**
     * @descriptions 根据课题ID获取课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.eintern.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @GetMapping("/project/{id}")
    public Result getById(@PathVariable("id")Long id) throws Exception{
        Project project = projectService.getProjectById(id);
        return Result.ok(project);
    }

    /**
     * @descriptions 根据课题ID获取课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.eintern.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @GetMapping("/project/type/{type}")
    public Result getByType(@PathVariable("type")Long type) throws Exception{
        List<Project> projectList = projectService.getProjectByType(type);
        return Result.ok(projectList);
    }

    /**
     * @descriptions 根据组长Id获取课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.eintern.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @GetMapping("/project/leader/{leaderId}")
    public Result getByLeaderId(@PathVariable Long leaderId) throws Exception{
        List<Project> projectList = projectService.getProjectByLeaderId(leaderId);
        return Result.ok(projectList);
    }

    /**
     * @descriptions 根据课程任务ID获取课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.eintern.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @GetMapping("/project/lessonTask/{lessonTaskId}")
    public Result getByLessonTaskId(@PathVariable Long lessonTaskId) throws Exception{
        List<Project> projectList = projectService.getProjectByLessonTaskId(lessonTaskId);
        return Result.ok(projectList);
    }

    /**
     * @descriptions 根据课程任务ID获取课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.eintern.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @GetMapping("/project/member/{projectId}")
    public Result getMemberById(@PathVariable Long projectId) throws Exception{
        List<UserProjectRecord> userProjectRecordList = projectService.getMemberById(projectId);
        return Result.ok(userProjectRecordList);
    }

    /**
     * @descriptions 新建课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.eintern.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @PostMapping("/project")
    public Result insertProject(@RequestBody Project projectReq) throws Exception{
        if(!Objects.equals(projectReq.getLeaderId(), getCurrentUserId())){
            return Result.fail().result(ResponseEnum.OPERATION_FAILED);
        }
        projectService.save(projectReq);
        projectService.createUserProjectRecord(getCurrentUserId(),projectReq.getId());
        return Result.ok(projectReq.getId());
    }
    /**
     * @descriptions 更新课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.eintern.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @PutMapping("/project")
    public Result updateProject(@RequestBody Project projectReq) throws Exception{
        System.out.println(projectReq);
        projectService.updateProject(projectReq);
        return Result.ok();
    }

    /**
     * @descriptions 删除课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.eintern.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @DeleteMapping ("/project")
    public Result deleteProject(@RequestParam Long projectId) throws Exception{
        Project project = projectService.getProjectById(projectId);
        if(!Objects.equals(project.getLeaderId(), getCurrentUserId())){
            return Result.fail().result(ResponseEnum.NOT_FOUND_USERID);
        }
        projectService.removeById(projectId);
        return Result.ok();
    }

    /**
     * @descriptions 邀请某人加入课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @PostMapping ("/project/invite")
    public Result inviteProjectByUserId(@RequestBody UserInviteRecord userInviteRecord){
        if(!checkUserIdAvailable(userInviteRecord.getReceiverId()) || !checkUserIdAvailable(userInviteRecord.getSenderId())){
            return Result.fail().result(ResponseEnum.NOT_FOUND_USERID);
        }
        //  检查对方是否已经加入课程小组
        Project project = projectService.getProjectById(userInviteRecord.getProjectId());
        if(project.getType()==0) {
            if (checkIsRepetitiveEnterLessonGroup(userInviteRecord.getProjectId(), userInviteRecord.getSenderId())) {
                return Result.fail().result(ResponseEnum.LESSON_GROUP_ERROR);
            }
        }
        Long projectId = userInviteRecord.getProjectId();
        Long receiverId = userInviteRecord.getReceiverId();
        Long senderId = getCurrentUserId();
        if(Objects.equals(senderId, receiverId)){
            return Result.fail().result(ResponseEnum.MESSAGE_ERROR);
        }
        String description;
        String outline;
        if(userInviteRecord.getDescription()!=null){
            description = userInviteRecord.getDescription();
        }else{
            description = "您好，我邀请您加入我的课题组。";
        }
        if(userInviteRecord.getOutline()!=null){
            outline = userInviteRecord.getOutline();
        }else{
            outline = "邀请加入课题组";
        }
        inviteService.inviteProjectByUserId(projectId,receiverId,senderId,description,outline);
        return Result.ok();
    }

    /**
     * @descriptions 同意邀请
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @PostMapping ("/project/invite/accept")
    public Result acceptInvite(@RequestBody UserInviteRecord userInviteRecord){
        if (!checkAuthenticationInvite(userInviteRecord)) return Result.fail().result(ResponseEnum.EXCEPTION);
        //  检查对方是否已经加入课程小组
        Project project = projectService.getProjectById(userInviteRecord.getProjectId());
        if(project.getType()==0){
            if(!checkIsRepetitiveEnterLessonGroup(userInviteRecord.getProjectId(),userInviteRecord.getSenderId())){
                UserLessonRecord userLessonRecord = lessonService.getLessonRecordByUserIdAndProjectId(userInviteRecord.getSenderId(),userInviteRecord.getProjectId());
                userLessonRecord.setGrouped(true);
                lessonService.updateLessonRecordByRecordId(userLessonRecord);
            }else{
                return Result.fail().result(ResponseEnum.LESSON_GROUP_ERROR);
            }
        }
        inviteService.acceptInviteById(userInviteRecord.getId());
        return Result.ok();
    }

    /**
     * @descriptions 拒绝邀请
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @PostMapping ("/project/invite/reject")
    public Result rejectInvite(@RequestBody UserInviteRecord userInviteRecord){
        if (!checkAuthenticationInvite(userInviteRecord)) return Result.fail().result(ResponseEnum.EXCEPTION);
        inviteService.rejectInviteById(userInviteRecord.getId());
        return Result.ok();
    }

    @CrossOrigin
    @ResponseBody
    @PutMapping("/project/invite/wechat")
    public Result updateInviteWechatState(@RequestBody UserInviteRecord userInviteRecord) throws Exception{
        Long loginUserId = getCurrentUserId();
        Long applyId = userInviteRecord.getId();
        UserInviteRecord userInviteRecord_inDB = inviteService.getById(applyId);
        if(!Objects.equals(userInviteRecord_inDB.getProjectId(), userInviteRecord.getProjectId()) || !Objects.equals(userInviteRecord_inDB.getReceiverId(), userInviteRecord.getReceiverId()) || !Objects.equals(userInviteRecord_inDB.getSenderId(), userInviteRecord.getSenderId())){
            return Result.fail().result(ResponseEnum.EXCEPTION);
        }
        if(!Objects.equals(userInviteRecord_inDB.getReceiverId(),loginUserId)){
            return Result.fail().result(ResponseEnum.OPERATION_FAILED);
        }
        userInviteRecord_inDB.setWechatExchangeState(userInviteRecord.getWechatExchangeState());
        inviteService.saveOrUpdate(userInviteRecord_inDB);
        return Result.ok();
    }

    @CrossOrigin
    @ResponseBody
    @PostMapping("/project/invite/wechat")
    public Result getInviteWechat(@RequestBody UserInviteRecord userInviteRecord) throws Exception{
        Long loginUserId = getCurrentUserId();
        Long applyId = userInviteRecord.getId();
        UserInviteRecord userInviteRecord_inDB = inviteService.getById(applyId);
        System.out.println(userInviteRecord_inDB.getWechatExchangeState());
        if(!Objects.equals(userInviteRecord_inDB.getProjectId(), userInviteRecord.getProjectId()) ||
                !Objects.equals(userInviteRecord_inDB.getReceiverId(), userInviteRecord.getReceiverId()) ||
                !Objects.equals(userInviteRecord_inDB.getSenderId(), userInviteRecord.getSenderId()))
        {
            return Result.fail().result(ResponseEnum.EXCEPTION);
        }
        if(userInviteRecord_inDB.getWechatExchangeState() != 1){
            return Result.fail().result(ResponseEnum.OPERATION_FAILED);
        }
        //  如果发出者与当前登录态用户id相同
        boolean isMine = Objects.equals(loginUserId, userInviteRecord.getSenderId());
        if(isMine){
            return Result.ok(userService.getWechatNumber(userInviteRecord.getReceiverId()));
        }else{
            return Result.ok(userService.getWechatNumber(userInviteRecord.getSenderId()));
        }
    }

    /**
     * @descriptions 判断用户是否有更新邀请状态的权限
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    private boolean checkAuthenticationInvite(UserInviteRecord userInviteRecord) {
        Long loginUserId = getCurrentUserId();
        return userInviteRecord.getReceiverId().equals(loginUserId);
    }

    /**
     * @descriptions 申请加入课题
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @PostMapping ("/project/apply")
    public Result applyProjectByUserId(@RequestBody UserApplyRecord userApplyRecord){
        Long projectId = userApplyRecord.getProjectId();
        if(!checkUserIdAvailable(userApplyRecord.getReceiverId()) || !checkUserIdAvailable(getCurrentUserId())){
            return Result.fail().result(ResponseEnum.NOT_FOUND_USERID);
        }
        //  检查对方是否已经加入课程小组
        Project project = projectService.getProjectById(userApplyRecord.getProjectId());
        if(project.getType()==0) {
            if (checkIsRepetitiveEnterLessonGroup(userApplyRecord.getProjectId(), userApplyRecord.getSenderId())) {
                return Result.fail().result(ResponseEnum.LESSON_GROUP_ERROR);
            }
        }
        Long receiverId = userApplyRecord.getReceiverId();
        Long senderId = getCurrentUserId();
        //  receiver 和 sender 不能一样
        if(Objects.equals(senderId, receiverId)){
            return Result.fail().result(ResponseEnum.MESSAGE_ERROR);
        }

        String description;
        String outline;
        if(userApplyRecord.getDescription()!=null){
            description = userApplyRecord.getDescription();
        }else{
            description = "您好，我申请加入您的课题组。";
        }
        if(userApplyRecord.getOutline()!=null){
            outline = userApplyRecord.getOutline();
        }else{
            outline = "申请加入课题组";
        }
        applyService.applyProjectByUserId(projectId,receiverId,senderId,description,outline);
        return Result.ok();
    }

    /**
     * @descriptions 同意申请
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @PostMapping ("/project/apply/accept")
    public Result acceptApply(@RequestBody UserApplyRecord userApplyRecord){
        //  检查用户权限
        if (!checkAuthenticationApply(userApplyRecord)) return Result.fail().result(ResponseEnum.EXCEPTION);
        //  检查对方是否已经加入课程小组
        Project project = projectService.getProjectById(userApplyRecord.getProjectId());
        if(project.getType()==0){
            if(!checkIsRepetitiveEnterLessonGroup(userApplyRecord.getProjectId(),userApplyRecord.getSenderId())){
                UserLessonRecord userLessonRecord = lessonService.getLessonRecordByUserIdAndProjectId(userApplyRecord.getSenderId(),userApplyRecord.getProjectId());
                userLessonRecord.setGrouped(true);
                lessonService.updateLessonRecordByRecordId(userLessonRecord);
            }else{
                return Result.fail().result(ResponseEnum.LESSON_GROUP_ERROR);
            }
        }
        //  同意用户加入课题组
        applyService.acceptApplyById(userApplyRecord.getId());
        return Result.ok();
    }

    /**
     * @descriptions 拒绝申请
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @PostMapping ("/project/apply/reject")
    public Result rejectApply(@RequestBody UserApplyRecord userApplyRecord){
        if (!checkAuthenticationApply(userApplyRecord)) return Result.fail().result(ResponseEnum.EXCEPTION);
        applyService.rejectApplyById(userApplyRecord.getId());
        return Result.ok();
    }

    //  修改微信交换状态
    @CrossOrigin
    @ResponseBody
    @PutMapping("/project/apply/wechat")
    public Result updateApplyWechatState(@RequestBody UserApplyRecord userApplyRecord) throws Exception{
        Long loginUserId = getCurrentUserId();
        Long applyId = userApplyRecord.getId();
        UserApplyRecord userApplyRecord_inDB = applyService.getById(applyId);
        if(!Objects.equals(userApplyRecord_inDB.getProjectId(), userApplyRecord.getProjectId()) || !Objects.equals(userApplyRecord_inDB.getReceiverId(), userApplyRecord.getReceiverId()) || !Objects.equals(userApplyRecord_inDB.getSenderId(), userApplyRecord.getSenderId())){
            return Result.fail().result(ResponseEnum.EXCEPTION);
        }
        if(!Objects.equals(userApplyRecord_inDB.getReceiverId(),loginUserId)){
            return Result.fail().result(ResponseEnum.OPERATION_FAILED);
        }
        userApplyRecord_inDB.setWechatExchangeState(userApplyRecord.getWechatExchangeState());
        applyService.saveOrUpdate(userApplyRecord_inDB);
        return Result.ok();
    }

    @CrossOrigin
    @ResponseBody
    @PostMapping("/project/apply/wechat")
    public Result getApplyWechat(@RequestBody UserApplyRecord userApplyRecord) throws Exception{
        Long loginUserId = getCurrentUserId();
        Long applyId = userApplyRecord.getId();
        UserApplyRecord userApplyRecord_inDB = applyService.getById(applyId);
        if(!Objects.equals(userApplyRecord_inDB.getProjectId(), userApplyRecord.getProjectId()) || !Objects.equals(userApplyRecord_inDB.getReceiverId(), userApplyRecord.getReceiverId()) || !Objects.equals(userApplyRecord_inDB.getSenderId(), userApplyRecord.getSenderId())){
            return Result.fail().result(ResponseEnum.EXCEPTION);
        }
        if(userApplyRecord_inDB.getWechatExchangeState() != 1){
            return Result.fail().result(ResponseEnum.OPERATION_FAILED);
        }
        //  如果发出者与当前登录态用户id相同
        boolean isMine = Objects.equals(loginUserId, userApplyRecord.getSenderId());
        if(isMine){
            return Result.ok(userService.getWechatNumber(userApplyRecord.getReceiverId()));
        }else{
            return Result.ok(userService.getWechatNumber(userApplyRecord.getSenderId()));
        }
    }

    /**
     * @descriptions 判断用户是否有更新申请状态的权限
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    private boolean checkAuthenticationApply(UserApplyRecord userApplyRecord) {
        Long loginUserId = getCurrentUserId();
        return userApplyRecord.getReceiverId().equals(loginUserId);
    }

    /**
     * @descriptions 判断用户是否有重复加入课程组
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    private boolean checkIsRepetitiveEnterLessonGroup(Long projectId,Long userId) {
        //  检查对方是否已经加入课程小组
        Project project = projectService.getProjectById(projectId);
        if(project.getType()==0){
            UserLessonRecord userLessonRecord = lessonService.getLessonRecordByUserIdAndProjectId(userId,projectId);
            //  用户不在该课程的名单中，不能加入小组
            if(userLessonRecord==null){
                return true;
            }
            return userLessonRecord.isGrouped();
        }
        return false;
    }

    /**
     * @descriptions 判断用户是否存在
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    private boolean checkUserIdAvailable(Long userId) {
        User user = userService.getById(userId);
        return !ObjectUtil.isEmpty(user);
    }

    /**
     * @descriptions 获取申请列表
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @GetMapping ("/project/apply")
    public Result getApplyList(){
        Long loginUserId = getCurrentUserId();
        return Result.ok(applyService.getApplyByUserId(loginUserId));
    }

    /**
     * @descriptions 获取邀请列表
     * @author 黄家宝
     * @date 2022/8/18 17:28
     * @return com.kapo.egroup.common.Result
     */
    @CrossOrigin
    @ResponseBody
    @GetMapping ("/project/invite")
    public Result getInviteList(){
        Long loginUserId = getCurrentUserId();
        return Result.ok(inviteService.getInviteByUserId(loginUserId));
    }

    private Long getCurrentUserId(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object user = authentication.getPrincipal();
        LoginUser loginUser = (LoginUser)user;
        return loginUser.getUserId();
    }
}
